﻿using System;
using System.Collections.Generic;
using Microsoft.Win32;

namespace WgpgCore
{
    internal delegate void ConfigDataChangedEventHandler(Object sender, String e);

    /// <summary>
    /// Read from and write to the registry.
    /// </summary>
    internal sealed class ConfigData
    {
        private readonly Object _lock = new Object();
        public event ConfigDataChangedEventHandler ConfigDataChanged;

        public String GetValue(String name, String defaultValue)
        {
            lock (_lock)
            {
                String entryValue;
                if (_entries.TryGetValue(name, out entryValue))
                    return entryValue;

                String result = (String)GetRegistryValue(name, defaultValue);

                _entries[name] = result;
                return result;
            }
        }

        public void SetValue(String name, String value)
        {
            lock (_lock)
            {
                String entryValue;
                if (_entries.TryGetValue(name, out entryValue))
                {
                    if (entryValue == value)
                        return;
                }

                _entries[name] = value;
                SetRegistryValue(name, value);

                if (ConfigDataChanged != null)
                    ConfigDataChanged(this, name);
            }
        }

        // ----------------------------------------------------------------------------------------

        private readonly Dictionary<String, String> _entries = new Dictionary<String, String>();

        // ----------------------------------------------------------------------------------------

        private static Object GetRegistryValue(String name, Object defaultValue)
        {
            String path = "";
            if (name.Contains("."))
            {
                Int32 pos = name.LastIndexOf('.');
                path = name.Substring(0, pos);
                path = path.Replace('.', '\\');
                path = '\\' + path;

                name = name.Substring(pos + 1);
            }

            using (RegistryKey currentUser = Registry.CurrentUser)
            {
                using (RegistryKey wgpg = currentUser.OpenSubKey("Software\\Wgpg" + path))
                {
                    return wgpg == null ? defaultValue : wgpg.GetValue(name, defaultValue);
                }
            }
        }

        private static void SetRegistryValue(String name, Object value)
        {
            String path = "";
            if (name.Contains("."))
            {
                Int32 pos = name.LastIndexOf('.');
                path = name.Substring(0, pos);
                path = path.Replace('.', '\\');
                path = '\\' + path;

                name = name.Substring(pos + 1);
            }

            using (RegistryKey currentUser = Registry.CurrentUser)
            {
                using (RegistryKey wgpg = currentUser.CreateSubKey("Software\\Wgpg" + path))
                {
                    if (wgpg != null)
                        wgpg.SetValue(name, value);
                }
            }
        }
    }
}
